/* COMPILING:
 * If you're compiling this with MSVC2010, you'll need to change the include and library directory
 * paths for opencv to reflect the path on your computer. I think that's all you have to do, but
 * I may be overlooking something.
 *
 * RUNNING:
 * Several dlls must be in the bin directory for this program to run without error:
 * opencv_core244.dll
 * opencv_core244d.dll
 * opencv_highgui244.dll
 * opencv_highgui244d.dll
 * opencv_imgproc244.dll
 * opencv_imgproc244d.dll
 * opencv_objdetect244.dll
 * opencv_objdetect244d.dll
 */

#include <iostream>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

int main(int argc, char* argv[])
{
	// Load in the haarcascade file that we'll use for face detection.
	const std::string FACE_CASCADE_NAME("haarcascade_frontalface_alt.xml");
	cv::CascadeClassifier face_cascade(FACE_CASCADE_NAME);
	if(face_cascade.empty())
	{
		std::cerr << "Failed to load " << FACE_CASCADE_NAME << std::endl;
		return -1;
	}

	// Load in an image containing a face.
	const std::string INPUT_IMAGE_NAME("lena.bmp");
	cv::Mat input_image = cv::imread(INPUT_IMAGE_NAME);
	if(input_image.empty())
	{
		std::cerr << "Failed to load" << INPUT_IMAGE_NAME << std::endl;
		return -1;
	}

	// Convert the image to grayscale and equalize the histogram.
	cv::Mat image_gray;
	cv::cvtColor(input_image, image_gray, CV_BGR2GRAY);
	cv::equalizeHist(image_gray, image_gray);

	// Attempt to detect one or more faces.
	std::vector<cv::Rect> faces;
	face_cascade.detectMultiScale(image_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));

	// Iterate over the detected faces and surround each one with an ellipse.
	std::for_each(faces.begin(), faces.end(), [&input_image](const cv::Rect& face_rect)
	{
		cv::Point center(face_rect.x + static_cast<int>(face_rect.width*0.5f), face_rect.y + static_cast<int>(face_rect.height*0.5f));
		cv::ellipse(input_image, center, cv::Size(static_cast<int>(face_rect.width*0.5f), static_cast<int>(face_rect.height*0.5f)), 0, 0, 360, cv::Scalar(0, 0, 255), 4, 8, 0);
	});

	cv::imshow("Face Detector", input_image);

	// Delay termination until some key is pressed. We want to give the user time to view the output.
	cv::waitKey();

	return 0;
}